package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xuecheng.base.exception.BusinessException;
import com.xuecheng.base.exception.CommonError;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanMediaService;
import com.xuecheng.content.service.TeachplanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {

    @Autowired
    private TeachplanMediaService teachplanMediaService;

    @Resource
    private TeachplanMapper teachplanMapper;



    /**
     * 根据课程id查询课程计划
     * @param courseId
     * @return
     */
    @Override
    public List<TeachplanDto> getTeachPlan(Long courseId) {
        //参数校验
        if (courseId == null||courseId<=0) {
            throw new BusinessException("参数为null/不合法");
        }
        List<TeachplanDto> teachpalnById = teachplanMapper.getAllTeachpalnById(courseId);
        if (teachpalnById==null ) BusinessException.cast(CommonError.QUERY_NULL);
        return teachpalnById;
    }

    /**
     * 新增/修改章节
     * @param teachplanDto
     */
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        if (teachplanDto == null) {
            BusinessException.cast(CommonError.REQUEST_NULL);
        }

        //若id为null则为添加
        if (teachplanDto.getId() == null) {
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(teachplanDto,teachplan);
            //确定排序字段
            // todo 是否合理？
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId,teachplan.getCourseId())
                    .eq(Teachplan::getParentid,teachplan.getParentid());
            int count = count(queryWrapper);
            teachplan.setOrderby(count+1);
            //添加
            boolean save = save(teachplan);
            if (!save) BusinessException.cast(CommonError.UNKOWN_ERROR);
        }else {
            //id不为null则为修改
            Teachplan teachplan = getById(teachplanDto.getId());
            BeanUtils.copyProperties(teachplanDto,teachplan);
            boolean res = updateById(teachplan);
            if (!res) BusinessException.cast(CommonError.UNKOWN_ERROR);
        }
    }

    /**
     * 删除章节
     * @param teachplanId
     */
    @Transactional
    @Override
    public void deleteTeachplan(Long teachplanId) {
        //1.参数校验
        if (teachplanId == null || teachplanId <= 0) {
            BusinessException.cast(CommonError.PARAMS_ERROR);
        }
        //2.查询该章节是否存在
        Teachplan teachplan = getById(teachplanId);
        if (teachplan == null) {
            BusinessException.cast(CommonError.QUERY_NULL);
        }
        //3. 判断大章节还是小章节
        if (teachplan.getGrade() == 1) {
            //若为大章节
            //判断是否还有小章节
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid,teachplanId);
            int count = count(queryWrapper);
            if (count != 0) {
                throw new BusinessException("课程计划信息还有子级信息，无法操作");
            }
        }else {
            // else 为小章节
            // 删除相关联的媒资
            LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
            //判断小章节是否关联媒质
            TeachplanMedia teachplanMedia = teachplanMediaService.getOne(queryWrapper);
            if (teachplanMedia!=null) {
                boolean remove = teachplanMediaService.remove(queryWrapper);
                if (!remove) BusinessException.cast(CommonError.UNKOWN_ERROR);
            }
        }
        //删除
        boolean res = removeById(teachplanId);
        // todo 使后面的记录的orderby字段-1
        LambdaUpdateWrapper<Teachplan> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Teachplan::getCourseId,teachplan.getCourseId())
                .eq(Teachplan::getParentid,teachplan.getParentid())
                .gt(Teachplan::getOrderby,teachplan.getOrderby());
        updateWrapper.setSql("orderby = orderby-1");
        boolean update = update(updateWrapper);
        if (!res) BusinessException.cast(CommonError.UNKOWN_ERROR);
    }

    /**
     * 章节下移
     * @param teachplanId
     */
    @Override
    public void moveDown(long teachplanId) {
        exchangeTeachplan(teachplanId,true);
    }

    /**
     * 章节上移
     * @param teachplanId
     */
    @Override
    public void moveUp(long teachplanId) {
        exchangeTeachplan(teachplanId,false);
    }

    /**
     * 绑定媒资
     * @param bindTeachplanMediaDto
     */
    @Transactional
    @Override
    public void binidTeachplanMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //校验当前章节是否已绑定媒资
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<TeachplanMedia>();
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        queryWrapper.eq(TeachplanMedia::getTeachplanId, teachplanId);
        TeachplanMedia teachplanMedia = teachplanMediaService.getOne(queryWrapper);
        if (teachplanMedia!=null) {
            //绑定则删除原绑定
            teachplanMediaService.removeById(teachplanMedia.getId());
        }
        //添加绑定
        TeachplanMedia teachplanMedia1 = new TeachplanMedia();
        BeanUtils.copyProperties(bindTeachplanMediaDto,teachplanMedia1);
        //查询章节信息
        Teachplan teachplan = getById(teachplanId);
        //set course_id
        teachplanMedia1.setCourseId(teachplan.getCourseId());
        //set media_fileName
        teachplanMedia1.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia1.setCreateDate(LocalDateTime.now());
        boolean res = teachplanMediaService.save(teachplanMedia1);
        if (!res) BusinessException.cast(CommonError.UNKOWN_ERROR);
    }

    /**
     * 交换章节位置
     * @param teachplanId
     * @param isDown
     */
    private void exchangeTeachplan(long teachplanId,boolean isDown ){
        //参数校验
        if (teachplanId <= 0) {
            BusinessException.cast(CommonError.PARAMS_ERROR);
        }
        //查询章节是否存在
        Teachplan teachplan = getById(teachplanId);
        if (teachplan==null) BusinessException.cast(CommonError.QUERY_NULL);
        //查询要交换的章节
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        if (isDown) {
            queryWrapper.eq(Teachplan::getOrderby,teachplan.getOrderby()+1);
        }else {
            queryWrapper.eq(Teachplan::getOrderby,teachplan.getOrderby()-1);
        }
        queryWrapper.eq(Teachplan::getParentid,teachplan.getParentid())
                .eq(Teachplan::getCourseId,teachplan.getCourseId());
        Teachplan exchangeTeachplan = getOne(queryWrapper);
        if (exchangeTeachplan == null) {
            if (isDown) {
                throw new BusinessException("章节无法再下移");
            }else {
                throw new BusinessException("章节无法再上移");
            }
        }
        //交换
        int temp = teachplan.getOrderby();
        teachplan.setOrderby(exchangeTeachplan.getOrderby());
        exchangeTeachplan.setOrderby(temp);
        boolean res = updateBatchById(Arrays.asList(teachplan, exchangeTeachplan));
        if (!res)BusinessException.cast(CommonError.UNKOWN_ERROR);
    }
}
